<template>
  <div style="width:900px;margin:0 auto;">
    1、数据源 <Select v-model="datasource.id" style="width:200px;margin-right: 20px;" placeholder="请先选择一个数据源">
      <Option v-for="item in datasource.list" :key="item.id" :value="item.id">{{ item.name }}</Option>
    </Select>
    <span v-if="database.isShow">数据库 </span>
    <Select v-if="database.isShow" v-model="database.name" style="width:200px;margin-right: 20px;" placeholder="选择数据库">
      <Option v-for="(item, index) in database.list" :key="index" :value="item">{{ item }}</Option>
    </Select>

    <div style="height:450px;margin: 20px auto">
      <div style="float:left">
        <div style="width:300px;">
          <Divider size="small">2、选择一张表</Divider>
        </div>
        <ul class="box even">
          <li v-for="item in tables" :key="item.tableName"><span class="right">
              <div class="notTooLong">{{ item.comment }}</div> &nbsp;&nbsp;<a href="javascript:void(9);"
                @click="selectedTableName = item.tableName">选择</a>
            </span>{{ item.tableName }}</li>
        </ul>
      </div>
      <img style="float:left;margin:180px 20px 0 20px"
        src="" />
      <div style="float:left">
        <div style="width:300px;">
          <Divider size="small">3、选择<span v-if="selectedTableName">表 [{{ selectedTableName }}] 的</span>{{ isSingleSelect
            ? '一个' : '' }}字段</Divider>
        </div>
        <ul class="box odd" style="margin-bottom:10px">
          <li v-for="item in fields" :key="item.name">
            <label>
              <input type="checkbox" v-model="item.checked" />&nbsp;
              <span class="right notTooLong">{{ item.comment }}</span>{{ item.name }}: <span
                style="color:lightgray">{{ item.type }}</span>
            </label>
          </li>
        </ul>

        <a v-if="!isSingleSelect" @click="selectAllField" style="padding-top:10px;">全选</a>
        <!-- | <a href="#" @click="getSelected">Test</a> -->
      </div>
    </div>
  </div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { get } from '../../../common/request';

export default defineComponent({
  props: {
    apiRoot: { type: String, required: true },  // 接口前缀
    isSingleSelect: { type: Boolean, default: false } // 是否只允许选择一个字段
  },
  data() {
    return {
      API: `${this.apiRoot}/datasource`,
      datasource: {
        id: 0,
        list: [],
        name: ''
      },
      database: {
        isShow: false,
        name: '',
        list: []
      },
      tables: [],
      selectedTableName: '',
      fields: [] as CheckableDataBaseColumnMeta[]
    };
  },

  mounted(): void {
    this.getDatasource();
  },

  methods: {
    /**
     * 获取数据源
     */
    getDatasource(): void {
      let params: any = { start: 0, limit: 999 };

      get(this.API, (j: RepsonseResult) => {
        if (j.status) {
          this.datasource.list = j.data;

          if (this.datasource.list[0])
            this.datasource.id = this.datasource.list[0].id; // 默认显示第一个数据源的
        } else
          this.$Message.error('获取数据源失败');
      }, params);
    },

    /**
     * 获取表
     */
    getTables(): void {
      let url: string = `${this.API}/${this.datasource.id}/all_tables_comment`;

      if (this.database.isShow)
        url += '?dbName=' + this.database.name;

      get(url, (j: RepsonseResult) => {
        if (j.status) {
          let arr: any[] = j.data as any[];
          arr.sort(sortFn);

          this.tables = arr;
          if (this.tables[0])
            this.selectedTableName = this.tables[0].tableName;
        } else
          this.$Message.error('获取表失败');
      });
    },

    /**
     * 获取字段
     */
    getFields(): void {
      let url: string = `${this.API}/${this.datasource.id}/table_all_column/${this.selectedTableName}`;

      if (this.database.isShow)
        url += '?dbName=' + this.database.name;

      get(url, (j: RepsonseResult) => {
        if (j.status) {
          let arr: any[] = j.data as any[];
          arr.sort(sortFn);

          this.fields = arr.map((item: CheckableDataBaseColumnMeta) => {
            let obj: any = item;
            item.isKey = obj.isKey === 'true';
            item.defaultValue = obj.default;
            (item as CheckableDataBaseColumnMeta).checked = false;

            return item;
          });
        } else
          this.$Message.error('获取字段列表失败');
      });
    },

    /**
     * 返回选择结果
     * 
     * @returns 
     */
    getSelected(): SelectedTable {
      let fields: CheckableDataBaseColumnMeta[] = this.fields.filter((item: CheckableDataBaseColumnMeta) => item.checked);
      let s: SelectedTable = { datasourceId: this.datasource.id, datasourceName: this.datasource.name, tableName: this.selectedTableName };

      if (this.isSingleSelect) {
        if (fields.length > 1) {
          this.$Message.warning('请只选择一个字段');
          return null;
        }

        s.field = fields[0];
      } else
        s.fields = fields;

      return s;
    },

    /**
     * 全选字段
     */
    selectAllField(): void {
      this.fields.forEach((item: CheckableDataBaseColumnMeta) => item.checked = true);
    },
    getDatabase(id: number): void {
      Xhr.xhr_get(this.API + '/../data_service/getDatabases', (j: RepsonseResult) => {
        if (j.status) {
          this.database.list = j.data;
          this.database.name = this.database.list[0]; // 默认显示第一个数据库的
        } else
          this.$Message.warning('获取数据库名失败');
      }, { datasourceId: id });
    }
  },
  watch: {
    'datasource.id'(v: number): void {
      this.getTables(); // 会重复执行，没有 库名 FIXME

      // 为了获取 getDatasourceName
      this.datasource.list.forEach((item: any) => {
        if (item.id == v) {
          this.datasource.name = item.name;

          if (item.crossDB) {// 显示选择库
            this.database.isShow = true;
            this.getDatabase(item.id);
          } else
            this.database.isShow = false;
        }
      });
    },
    selectedTableName(v: string): void {
      this.getFields();
    },
    'database.name'(dbName: string): void {
      this.getTables();
    }
  }
});

const sortFn = (a: any, b: any): number => {
  if (a.tableName > b.tableName)
    return 1;

  if (a.tableName < b.tableName)
    return -1;

  return 0;
}
</script>

<style lang="less" scoped>
.notTooLong {
  display: inline-block;
  color: gray;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 190px;
  white-space: nowrap;
  vertical-align: middle;
}

.box {
  width: 400px;
  height: 400px;
  // margin: 30px 0;
  border: 1px solid lightgray;
  overflow-x: auto;

  li {
    list-style: none;
    padding: 5px 15px;

    // background-color: #e3e3e3;
    &:hover {
      color: black;
    }

    span.right {
      float: right;
    }

    label {
      cursor: pointer;
    }
  }
}

.box.even {
  li:nth-child(even) {
    background-color: #f0f0f0;
  }
}

.box.odd {
  li:nth-child(odd) {
    background-color: #f0f0f0;
  }
}
</style>